package main

import (
	"fmt"
	"reflect"
)

type Monster struct {
	Name  string `json:"name"`
	Age   int    `json:"age"`
	Score float32
	Sex   string
}

func (this Monster) Print() {
	fmt.Println("start")
	fmt.Println(this)
	fmt.Println("end")
}
func (this Monster) GetSum(n1, n2 int) int {
	return n1 + n2
}
func (this Monster) Set(name string, age int, score float32, sex string) {
	this.Name = name
	this.Age = age
	this.Sex = sex
	this.Score = score
}
func testStruct(b interface{}) {
	rType := reflect.TypeOf(b)
	rVal := reflect.ValueOf(b)
	kind := rVal.Kind()
	fmt.Printf("kind is %v\n", kind)
	if kind != reflect.Struct {
		fmt.Println("expect struct")
		return
	}
	//获取结构体的字段
	filedNum := rVal.NumField()
	fmt.Printf("结构体字段数量是%v\n", filedNum)
	//遍历
	for i := 0; i < filedNum; i++ {
		fmt.Printf("field %d  值为=%v\n", i, rVal.Field(i))
		tagValue := rType.Field(i).Tag.Get("json")
		if tagValue != "" {
			fmt.Printf("tag的值为%v\n", tagValue)
		}
	}
	//获取结构体方法的数量
	methodNum := rVal.NumMethod()
	fmt.Printf("结构体方法数量为%v", methodNum)
	//获取一个方法
	rVal.Method(1).Call(nil)
	//调用结构体第一个方法
	var params []reflect.Value
	params = append(params, reflect.ValueOf(10))
	params = append(params, reflect.ValueOf(100))
	result := rVal.Method(0).Call(params)
	fmt.Printf("第一个方法结果是%v\n", result[0].Int()) //返回的结果是【】reflect.value
}
func main() {
	monster := Monster{
		Name:  "狐狸精",
		Age:   400,
		Score: 5000,
		Sex:   "female",
	}
	testStruct(monster)
}
